论坛首页 Java企业应用论坛

开发过程中事务控制

浏览 4923 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-12-21  

一、在JDBC连接中开启事务,调用完成后关闭连接(传统方式不推荐使用)

private static DataSource ds;

	static{
		try{
			Properties prop = new Properties();
			InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
			prop.load(in);
			BasicDataSourceFactory factory = new BasicDataSourceFactory();
			ds = factory.createDataSource(prop);
		}catch (Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}

	public void transfer() throws SQLException{
		Connection conn = null;
		try{
			conn = JdbcUtils.getConnection();
			conn.setAutoCommit(false);
			//对数据进行操作			
			conn.commit();
		}finally{
			if(conn!=null) conn.close();
		}
	}

 二、用ThreadLocal类在线程上绑定一个连接

private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();

 在获得连接的时候就绑定到threadLocal 上

public static Connection getConnection() throws SQLException{
		try{
			//得到当前线程上绑定的连接
			Connection conn = threadLocal.get();
			if(conn==null){  //代表线程上没有绑定连接
				conn = ds.getConnection();
				threadLocal.set(conn);
			}
			return conn;
		}catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

 然后开启事务

public static void startTransaction(){
		try{
			//得到当前线程上绑定连接开启事务
			Connection conn = threadLocal.get();
			if(conn==null){  //代表线程上没有绑定连接
				conn = ds.getConnection();
				threadLocal.set(conn);
			}
			conn.setAutoCommit(false);
		}catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

 

执行完相应操作后提交事务

public static void commitTransaction(){
		try{
			Connection conn = threadLocal.get();
			if(conn!=null){
				conn.commit();
			}
		}catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

 

最后关闭连接

	public static void closeConnection(){
		try{
			Connection conn = threadLocal.get();
			if(conn!=null){
				conn.close();
			}
		}catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
			//千万注意,解除当前线程上绑定的链接(从threadlocal容器中移除对应当前线程的链接)
			threadLocal.remove();   
		}
	}

 

 第三种方法是用spring中的事务管理器,本次不做讨论

   发表时间:2012-12-25  
spring事物,jdbc事物是重点
0 请登录后投票
   发表时间:2012-12-25  
请问LZ, 传统方式和threadlocal有什么区别?
0 请登录后投票
   发表时间:2012-12-25  
请问这与传统的 优缺点怎么比较~~~~
0 请登录后投票
   发表时间:2012-12-25  
个人认为每个访问是一个线程,用threadlocal,线程是安全的。
而且事务是绑定到线程的,事务一直存在,只要用get方法就可以拿到事务,
方便做很多事情。
0 请登录后投票
   发表时间:2012-12-25  
看到一个便捷之处:
在本线程中共享数据库链接,不用在方法调用的时候把数据库链接作为参数进行传递。
至于事务相关的好处暂时没有看到。
0 请登录后投票
   发表时间:2012-12-26  
其实是个不错的思路,我一直在考虑,数据库事务可以使用存储过程,JAVA这边如果多个方法形成事务有点难办,就是不知道怎么长时间持有一个连接。你的办法不错呢。把这些代码写到过滤器中,servlet层就可以直接使用了,这样就可以将多个JAVA方法做成事务了
0 请登录后投票
   发表时间:2012-12-26  

如果这个是应用在servlet环境,事实上servlet的请求是多线程的,但是由线程池维护,那么上述实现就变成servlet线程池的每个坑一个数据源链接(正好实现了类似连接池的效果)。

但是要注意,应该去掉ThreadLocal.remove() ,不要觉得会内存泄漏,线程结束的时候会释放资源的。 同一个线程remove后再get,那就又要新创建数据源链接,那还不如不要用static ,不会比每个请求都实例化新的链接并新开链接来得快的。

0 请登录后投票
   发表时间:2012-12-27  
。。。。。。。你们难道不知道spring事务的线程内部也是放到threadlocal里面的么?有什么好说的
0 请登录后投票
   发表时间:2012-12-27  
xubindehao 写道
。。。。。。。你们难道不知道spring事务的线程内部也是放到threadlocal里面的么?有什么好说的

哈哈 这个真不知道  但是我只知道可以这么用  么看过源码
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics