写入事务 - .NET SDK
Overview
除了读取对象外,您还可以在 Realm 中创建、更新和删除对象。 由于这些操作会修改域的状态,因此我们将其称为“写入”,并且对Realm的所有写入都必须在事务中进行。
事务是一系列读写操作,Realm 将其视为单个不可分割的操作。 事务是全有或全无操作:事务中的所有操作要么成功,要么事务中的所有操作都不生效。
Realm 一次只允许一个打开的事务。 Realm 会阻止其他线程上的其他写入,直到打开的事务完成。 这可确保在事务中从 Realm 读取值时不存在争用情况。
当事务中的所有操作完成后,Realm 要么提交事务,要么取消事务:
当 Realm 提交事务时,Realm 会将所有更改写入磁盘。 对于同步 Realm,SDK 会将更改排队以便与 Atlas App Services 同步。
当 Realm 取消写事务(write transaction)时(如事务中的操作导致错误时),所有更改都将被丢弃(或“回滚”)。
发起事务
.NET SDK提供了一个简单的API ,可用于大多数写入操作。 Write()和WriteAsync()方法将所有命令包装到单个ACID 事务中,然后提交该ACID 事务。
Write()
和WriteAsync()
方法是使用BeginWrite()和Transaction.Commit()方法及其Async
对应方法的简写。 在大多数情况下,这两种写入方法都可以满足您的需求。 如果需要更好地控制ACID 事务,请将BeginWrite()
与以下Transaction
方法之一结合使用:
以下代码展示了如何使用这两种方法:
// Instantiate a class, as normal. var dog = new Dog { Id = 42, Name = "Max", Age = 5 }; // Open a thread-safe transaction. realm.Write(() => { // Add the instance to the realm. realm.Add(dog); });
// Open a thread-safe transaction. using (var transaction = realm.BeginWrite()) { // At this point, the TransactionState is "Running": // transaction.State == TransactionState.Running try { // Perform a write op... realm.Add(myDog); // Do other work that needs to be included in // this transaction if (transaction.State == TransactionState.Running) { transaction.Commit(); } } catch (Exception ex) { Console.WriteLine(ex.Message); // Something went wrong; roll back the transaction if (transaction.State != TransactionState.RolledBack && transaction.State != TransactionState.Committed) { transaction.Rollback(); } } }
注意
CancelationTokens
与大多数C#异步方法一样, WriteAsync 、 BeginWriteAsync 和 CommitAsync 方法可以采用 CancellationToken 作为参数,为您提供在进程完成之前取消操作的选项。
检查事务状态
SDK 提供了包含当前ACID 事务状态的TransactionState属性。 可以使用TransactionState
确保不会提交或回滚ACID 事务两次:
// Open a thread-safe transaction. using (var transaction = realm.BeginWrite()) { // At this point, the TransactionState is "Running": // transaction.State == TransactionState.Running try { // Perform a write op... realm.Add(myDog); // Do other work that needs to be included in // this transaction if (transaction.State == TransactionState.Running) { transaction.Commit(); } } catch (Exception ex) { Console.WriteLine(ex.Message); // Something went wrong; roll back the transaction if (transaction.State != TransactionState.RolledBack && transaction.State != TransactionState.Committed) { transaction.Rollback(); } } }