DML 选项
在 DML 语句执行的时候可以设置选项。这些选项用 DML.Options 类来表示。
完整的介绍在中。
在建立一个 DML.Options 实例之后,可以使用 setOptions() 函数来使用。
比如:
Database.DMLOptions dmo = new Database.DMLOptions();dmo.allowFieldTruncation = true;Account a = new Account();// 设置 Account 的各种属性值// ...// 将 DML 选项设置到 Account 对象中,然后插入。这些选项就会被应用了a.setOptions(dmo);insert a;
可用的属性主要有:
- allowFieldTruncation:设置是否自动截断数据,布尔值。比如当某字符串太长,超过了系统中相应字段的长度,DML 语句可以自动截断字符串,从而顺利保存在相应的字段中
- assignmentRuleHeader:用于建立个案(case)和潜在客户(lead)对象,包括布尔型选项 useDefaultRule 和 ID 类型选项 assignmentRuleID
- dupicateRuleHeader:用于设置当一条记录被认为重复的时候,如何处理,包括一个布尔型选项 allowSave 来设置是否允许保存
- emailHeader:可以设置在某些事件满足时是否自动发送电子邮件
- localeOptions:设置相关的语言
- optAllOrNone:设置当某条记录出现错误的时候,是否要继续处理其他的记录
SavePoint 对象和数据回滚
SavePoint 对象可以将 DML 语句的执行结果回滚到之前的状态,多用于 DML 出错的情况下恢复数据。基本用法如下:
Savepoint sp1 = Database.setSavepoint();Account a = new Account();// 设置 Account 对象的属性// ...insert a;Savepoint sp2 = Database.setSavepoint();// 更改 Account 对象的属性// ...update a// 回滚数据到 sp1 的状态Database.rollback(sp1);
需要注意的是:
- 在 rollback() 函数回滚到很早的 SavePoint 对象之后,其后面的 SavePoint 对象就都失效了。比如上面的例子在回滚到 sp1 的状态后,变量 sp2 就失效了
- 回滚数据的操作也被计算到 DML 的限制中,所以如果回滚太多 DML 语句,有可能超出限制,出错
锁住数据记录
在 SOQL 语句中更新某条记录时,我们可以使用 FOR UPDATE 关键字锁住当前记录,使得它不会被其他的线程影响,从而导致数据出错。
比如:
Account [] accts = [SELECT Id FROM Account LIMIT 2 FOR UPDATE]; // 这两条 Account 数据会被锁住,直至当前 Apex 的代码段执行完毕
注意,ORDER BY 语句不能和 FOR UPDATE 一起使用。
当一条记录被锁住之后,其他线程如果也想对它进行更新,则要等待它被解锁。如果等待超过10秒,就会出错。