- ThreadLocal与事务,服务器(如tomcat)也维护了一个线程池。
可以结合如dbutils包的QueryRunner等,在业务层实现事务控制(确保一个事务中的连接为同一个,成功则提交,异常则回滚)。
示例一:
/**
* 连接的工具类,它用于从数据源中获取一个连接,并且实现和线程的绑定
* utils.ConnectionUtils
*/
public class ConnectionUtils {
private ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public Connection getThreadConnection() {
try{
Connection conn = tl.get();
if (conn == null) {
conn = dataSource.getConnection();
tl.set(conn);
}
//4.返回当前线程上的连接
return conn;
}catch (Exception e){
throw new RuntimeException(e);
}
}
/**
* 把连接和线程解绑
*/
public void removeConnection(){
tl.remove();
}
}
// utils.TransactionManager
public class TransactionManager {
private ConnectionUtils connectionUtils;
public void setConnectionUtils(ConnectionUtils connectionUtils) {
this.connectionUtils = connectionUtils;
}
public void beginTransaction(){
try {
connectionUtils.getThreadConnection().setAutoCommit(false);
}catch (Exception e){
e.printStackTrace();
}
}
public void commit(){
try {
connectionUtils.getThreadConnection().commit();
}catch (Exception e){
e.printStackTrace();
}
}
public void rollback(){
try {
connectionUtils.getThreadConnection().rollback();
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 释放连接
*/
public void release(){
try {
connectionUtils.getThreadConnection().close();//还回连接池中
connectionUtils.removeConnection();
}catch (Exception e){
e.printStackTrace();
}
}
}
- 详解Tomcat线程池原理及参数释义:
https://www.cnblogs.com/liuchuanfeng/p/6876645.html; - Proxy(),动态代理的方式,结合spring给1的事务解耦:
/**
* 用于创建Service的代理对象的工厂
* factory.BeanFactory
*/
public class BeanFactory {
private IAccountService accountService;
private TransactionManager txManager;
public void setTxManager(TransactionManager txManager) {
this.txManager = txManager;
}
public void setAccountService(IAccountService accountService) {
this.accountService = accountService;
}
/**
* 获取Service代理对象
* @return
*/
public IAccountService getAccountService() {
return (IAccountService)Proxy.newProxyInstance(accountService.getClass().getClassLoader(),
accountService.getClass().getInterfaces(),
new InvocationHandler() {
/**
* 添加事务的支持
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object rtValue = null;
try {
txManager.beginTransaction();
rtValue = method.invoke(accountService, args);
txManager.commit();
return rtValue;
} catch (Exception e) {
txManager.rollback();
throw new RuntimeException(e);
} finally {
txManager.release();
}
}
});
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:bean.xml")
public class AccountServiceTest {
@Autowired
@Qualifier("proxyAccountService") // 使用注解和xml注入bean
private IAccountService as;
@Test
public void testTransfer(){
as.transfer("aaa","bbb",100f);
}
}