如何在自动提交打开或关闭的情况下注入数据源,无论方法是否在事务中 运行
How to inject a datasource with autocommit on or off whether a method is run inside a transaction or not
我有:
- JOOQ 中的一个 DAO class,在其构造函数中采用
javax.sql.DataSource
,它由 Guice 注入
- 从 DAO class
调用方法的服务 class
我想:
- 能够将服务中的一些方法注释class作为需要事务的方法
可能的解决方案:https://github.com/jOOQ/jOOQ/tree/master/jOOQ-examples/jOOQ-spring-guice-example i.d.:
- 当一个方法被注释为
Transactional
注释时调用的方法拦截器
- 如果有异常,方法拦截器调用
rollback()
,如果一切正常,则调用 commit()
- Guice 提供一个
javax.sql.DataSource
(BoneCP池连接)
- BoneCP 池连接的
defaultAutoCommit
属性设置为 false
最后,我的问题:
- 我希望将
autocommit
设置为 false
的数据源注入到 所有方法 中,这些方法是从带有 [=20 注释的方法中调用的=],在所有其他情况下,autocommit
的数据源设置为 true
如何实现?
有一个简单但不优雅的方法:创建两个DataSource实例并适当地注入。
对于单个 DataSource 实例,还有一种更复杂的方法。大致:
- AutoCommit 是 java.sql.Connection 中的一个 属性,它有一个 setter。
- 实施 org.jooq.ConnectionProvider 让 JOOQ 使用您的 DataSource 实例。
这个 ConnectionProvider 实现会有一个特殊的方法,例如startTransaction() 可以使用 autocommit=false 创建连接并将其缓存在 ThreadLocal 成员中。即
Connection conn = dataSource.createConnection();
conn.setAutoCommit(false);
threadLocal.set(conn);
return conn;
ConnectionProvider.acquire() 会像(简化版)那样做:
return threadLocal.get() != null ?
threadLocal.get() :
dataSource.createConnection();
另外两个"special"方法是commit()和rollback()——它们会对缓存的连接做相应的操作,关闭连接并从threadLocal中移除。
@Transactional 方法拦截器将调用 "special" 方法
try {
connectionProvider.startTransaction();
interceptedMethod.invoke();
connectionProvider.commit();
} catch (Exception e) {
connectionProvider.rollback();
}
本质上,这是最简单的事务管理器。
我有:
- JOOQ 中的一个 DAO class,在其构造函数中采用
javax.sql.DataSource
,它由 Guice 注入
- 从 DAO class 调用方法的服务 class
我想:
- 能够将服务中的一些方法注释class作为需要事务的方法
可能的解决方案:https://github.com/jOOQ/jOOQ/tree/master/jOOQ-examples/jOOQ-spring-guice-example i.d.:
- 当一个方法被注释为
Transactional
注释时调用的方法拦截器 - 如果有异常,方法拦截器调用
rollback()
,如果一切正常,则调用commit()
- Guice 提供一个
javax.sql.DataSource
(BoneCP池连接) - BoneCP 池连接的
defaultAutoCommit
属性设置为false
最后,我的问题:
- 我希望将
autocommit
设置为false
的数据源注入到 所有方法 中,这些方法是从带有 [=20 注释的方法中调用的=],在所有其他情况下,autocommit
的数据源设置为true
如何实现?
有一个简单但不优雅的方法:创建两个DataSource实例并适当地注入。
对于单个 DataSource 实例,还有一种更复杂的方法。大致:
- AutoCommit 是 java.sql.Connection 中的一个 属性,它有一个 setter。
- 实施 org.jooq.ConnectionProvider 让 JOOQ 使用您的 DataSource 实例。
这个 ConnectionProvider 实现会有一个特殊的方法,例如startTransaction() 可以使用 autocommit=false 创建连接并将其缓存在 ThreadLocal 成员中。即
Connection conn = dataSource.createConnection(); conn.setAutoCommit(false); threadLocal.set(conn); return conn;
ConnectionProvider.acquire() 会像(简化版)那样做:
return threadLocal.get() != null ? threadLocal.get() : dataSource.createConnection();
另外两个"special"方法是commit()和rollback()——它们会对缓存的连接做相应的操作,关闭连接并从threadLocal中移除。
@Transactional 方法拦截器将调用 "special" 方法
try { connectionProvider.startTransaction(); interceptedMethod.invoke(); connectionProvider.commit(); } catch (Exception e) { connectionProvider.rollback(); }
本质上,这是最简单的事务管理器。