通常一个业务操作会涉及多张数据库表,这就要求方法的实现本身就拥有事务功能以保证ACID,而不能完全靠方法调用者保证一定会在事务上下文中调用该方法。并且还需要考虑到方法内部的事务可以加入到外部事务中。
下面这个运算逻辑介绍如何在方法里使用一个事务。executeSqlArray()也在DAOTest.java中。
/**
* 执行多条sql.
*
* @param dsName
* 数据源的名字.
* @param sqls
* 要执行的sql数组.
*/
@Bizlet
(value =
"执行多条sql"
, params = {
@BizletParam
(index =
0
, defaultValue =
"default"
, type = CONSTANT, paramAlias=
"ds"
),
@BizletParam
(index =
1
, paramAlias=
"sqls"
) })
public
static
void
executeSqlArray(String dsName, String[] sqls) {
if
(dsName ==
null
|| dsName.length() ==
0
)
dsName =
"default"
;
ITransactionManager txManager = TransactionManagerFactory
.getTransactionManager();
txManager.begin(ITransactionDefinition.PROPAGATION_REQUIRED,
ITransactionDefinition.ISOLATION_DEFAULT);
Connection conn = ConnectionHelper
.getCurrentContributionConnection(dsName);
Statement stmt =
null
;
try
{
stmt = conn.createStatement();
for
(String sql : sqls) {
stmt.execute(sql);
}
close(stmt);
close(conn);
txManager.commit();
}
catch
(Throwable e) {
close(stmt);
close(conn);
txManager.rollback();
throw
new
RuntimeException(e);
}
}
|
对比执行单条sql的运算逻辑executeSql(),可以发现executeSqlArray()中主要是多了ITransactionManager txManager,以及关闭Connection的位置不同。
ITransactionManager是EOS提供的事务管理器,事务开始时指明了事务传播方式和事务隔离级别。
- 事务传播方式是ITransactionDefinition.PROPAGATION_REQUIRED,说明了如果调用该运算逻辑的外部没有事务就会新启动一个事务,如果外部已经有事务,该方法就加入外部的事务;
- 事物隔离级别是ITransactionDefinition.ISOLATION_DEFAULT,说明使用默认的隔离级别。
关于事务的更详细说明请参见《EOS基础参考手册》的"事务管理"部分。
注意
- 获取连接一定要在事务begin之后;
- 关闭连接一定要在事物commit/rollback之前。