最近我开始了一个Android应用程序项目。我需要尽可能地管理数据。
所以我选择了Realm并对它进行了一些修补。
但我遇到了一些错误。但我不知道为什么会发生这种错误。
错误是
不允许嵌套交易。在每个beginTransaction()之后使用commitTransaction()。
我的代码在下面。
public class CuratorApplication extends Application {
private Realm realm;
@Override
public void onCreate() {
super.onCreate();
Log.e("debug", "Application class create!!");
configureRealmDatabase(this);
}
private void configureRealmDatabase(Context context){
RealmConfiguration config = new RealmConfiguration.Builder(context)
.name("curator.realm")
.build();
Realm.setDefaultConfiguration(config);
}
}
我按照here
中的描述在Application类中注册域我试图在活动中进行交易。但它显示错误。 :(
package com.nolgong.curator.screen;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.nolgong.curator.R;
import com.nolgong.curator.model.retrofit.Game;
import com.nolgong.curator.model.retrofit.GameInformation;
import com.nolgong.curator.model.retrofit.Team;
import com.nolgong.curator.network.NetworkClient;
import java.io.IOException;
import java.util.Properties;
import io.realm.Realm;
import io.realm.exceptions.RealmPrimaryKeyConstraintException;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class IntroActivity extends AppCompatActivity {
private Button confirmBtn;
private EditText confirmText;
private Realm realm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intro);
setUp();
registerListener();
}
private String getProperty() throws IOException{
Properties properties = new Properties();
properties.load(getResources().openRawResource(R.raw.config));
String property = properties.getProperty("serverAddress");
Log.e("debug", "Property : " + property);
return property;
}
private void setNetworkClient(String serverAddress){
Log.e("debug", "Address : " + serverAddress);
NetworkClient.getInstance(serverAddress);
}
private void setUp(){
try {
setNetworkClient(getProperty());
} catch (IOException e){
Log.e("debug", "set network" + e);
}
confirmBtn = (Button)findViewById(R.id.intro_confirm);
confirmText = (EditText)findViewById(R.id.intro_input);
realm = Realm.getDefaultInstance();
Log.e("debug", "transaction state : " + realm.isInTransaction());
Log.e("debug", "CONFIGURATION : \n" + realm.getConfiguration());
}
private void registerListener(){
confirmBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String teamId = confirmText.getText().toString();
Integer digit = Integer.valueOf(teamId);
Log.e("debug", digit + "");
NetworkClient.getInstance().login(digit, new Callback<GameInformation>() {
@Override
public void onResponse(Call<GameInformation> call, Response<GameInformation> response) {
int responseCode = response.code();
switch (responseCode){
case 200:
GameInformation gameInformation = response.body();
Log.e("debug", "game information " + gameInformation.toString());
Game game = gameInformation.getGame();
Team team = gameInformation.getTeam();
updateGameToRealm(game);
updateTeamToRealm(team);
break;
default:
Log.e("debug", "Maybe something happened.");
break;
}
}
@Override
public void onFailure(Call<GameInformation> call, Throwable t) {
Log.e("debug", "Login fail :" + t.toString());
}
});
}
});
}
private void updateGameToRealm(Game game){
com.nolgong.curator.model.database.Game rGame = new com.nolgong.
curator.model.database.Game(game.getId(), game.getDate(),
game.getSession(), game.getRunningTime());
realm.beginTransaction();
try {
realm.copyToRealm(rGame);
} catch (RealmPrimaryKeyConstraintException e){
Log.e("debug", e.toString());
realm.cancelTransaction();
} finally {
realm.commitTransaction();
}
}
private void updateTeamToRealm(Team team){
com.nolgong.curator.model.database.Team rTeam = new com.nolgong.
curator.model.database.Team(team.getId(), team.getMembers(),
team.getGameId(), team.isClientDataSynced(),
team.getJob(), team.getDigit(),
team.getPoint());
realm.beginTransaction();
try {
realm.copyToRealm(rTeam);
} catch (RealmPrimaryKeyConstraintException e){
Log.e("debug", e.toString());
realm.cancelTransaction();
} finally {
realm.commitTransaction();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
realm.close();
}
}
为什么领域显示错误?我使用得当吗?或者这只是一个错误? 请帮帮我..
答案 0 :(得分:2)
正如错误所说,
不允许嵌套交易。在每个beginTransaction()之后使用commitTransaction()。
这意味着你不能做这样的事情:
realm.beginTransaction();
...
realm.beginTransaction();
realm.commitTransaction();
beginTransaction()
来电之后必须是commitTransaction()
或cancelTransaction()
来电。
强烈建议您使用executeTransaction()
代替begin/cancel/commit
,因为它更易于使用,并自动处理异常取消。
编辑:在使用cancelTransaction()
回滚后,您不应提交交易。
请尝试将begin/cancel/commit
替换为executeTransaction()
,看看会发生什么。
此外,您可以尝试将copyToRealm()
替换为copyToRealmOrUpdate()
。
我认为您可能会遇到this issue因为您遇到故障的UI线程上的多个事务,但我实际上并不确定。
<强> EDIT2:强>
private void updateGameToRealm(Game game){
Realm realm = null;
try {
realm = Realm.getDefaultInstance();
final com.nolgong.curator.model.database.Game rGame = new com.nolgong.
curator.model.database.Game(game.getId(), game.getDate(),
game.getSession(), game.getRunningTime());
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(rGame);
}
});
} finally {
if(realm != null) {
realm.close();
}
}
}
private void updateTeamToRealm(Team team){
Realm realm = null;
try {
realm = Realm.getDefaultInstance();
final com.nolgong.curator.model.database.Team rTeam = new com.nolgong.
curator.model.database.Team(team.getId(), team.getMembers(),
team.getGameId(), team.isClientDataSynced(),
team.getJob(), team.getDigit(),
team.getPoint());
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm.copyToRealmOrUpdate(rTeam);
}
});
} finally {
if(realm != null) {
realm.close();
}
}
}
答案 1 :(得分:1)
问题在这里:https://github.com/realm/realm-java/issues/542
您的领域交易代码应与此类似:
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement spanElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//span[text() = 'History']")));
Actions builder = new Actions(driver);
builder.moveToElement(spanElement).perform();
答案 2 :(得分:0)
根据我的最佳解决方案是启动领域交易 realm.executeTransactionAsync方法 如果使用此executeTransactionAsync方法,则relam处理begin事务,提交事务本身
我在插入或更新数据时也遇到了同样的错误,然后我找到了这个方法, 下面是我如何使用的样本
public void saveUserInfo(final UserDto userDto){
realm = Realm.getDefaultInstance();
realm.executeTransactionAsync(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
realm = Realm.getDefaultInstance();
realm.copyToRealmOrUpdate(userDto);
//realm.commitTransaction();
}
}, new Realm.Transaction.OnSuccess() {
@Override
public void onSuccess() {
EventBus.getDefault().post(new OnUserSaveEvent(true));
realm.close();
}
}, new Realm.Transaction.OnError() {
@Override
public void onError(Throwable error) {
realm.close();
}
});
}