事务管理
事务管理
MYSQL中的事务
*开启事务:start transaction
提交:commit;
回滚:rollback;
JDBC事务
在jdbc中处理事务,都是通过Connection完成的!
在同一事务中所有的操作都在使用同一个Connection对象
Connection中的三个方法与事务有关:
setAutoCommit(boolean):设置是否为自动事务提交。如果为true,表示每一条单独的SQL都是一个单独的事务。
如果设置false,就相当于开启了事务;con.setAutoCommit(false)表示开启事务!!!)
commit():提交结束书屋
rollback():回滚结束事务
jdbc处理事务的代码格式:
try{
con.setAutoCommit(false);
...
...
con.commit();
}catch(){
con.rollback();
}
事务的隔离级别
1.事务的并发读问题
*脏读:读取到另一个事务未提交数据
*不可重复读:两次读取不一致
*幻读(虚读):督导另一事务已提交数据
2.并发事务问题
*脏读:读到另一个事务的未提交更新数据,即读取到了脏数据
*不可重复读:对同一记录的两次读取不一致,因为另一事务对该记录做了修改
*幻读:对同一张表的两次查询不一致,因为另一事务插入了一条记录
3.四大隔离级别
用来防止并发问题
*serializable(串行化)
不会出现任何并发问题,因为它是对同一数据的访问是串行的,非并发访问的
性能最差
*repeatable read(可重复读)(mysql)
防止脏读和不可重复读,不能处理幻读问题
性能比serializable好
*read committed(读已提交数据)(oracle)
防止脏读,没有处理不可重复读,也没有处理幻读
性能比repeatable read好
*read uncommitted(读未提交数据)
可能出现并发问题
性能最好
查询数据库的隔离级别:
SELECT @@tx_isolation;
设置当前连接的隔离级别:settransaction isolationlevel [4选1]
JDBC设置隔离级别:
con.setTransactionIsolation(int level)
可选参数:
Connection.TRANSACTION_READ_UNCOMMITTED;
Connection.TRANSACTION_READ_COMMITTED;
Connection.TRANSACTION_REPEATABLE_READ;
Connection.TRANSACTION_SERIALIZABLE;
package cn.itcast.demo; import java.sql.Connection; import java.sql.PreparedStatement; public class AccountDao { public void updateBalance(Connection con,String name,double balance){ try{ String sql="UPDATE account SET balance=balance+? WHERE aname=?"; PreparedStatement pstmt=con.prepareStatement(sql); pstmt.setDouble(1, balance); pstmt.setString(2, name); pstmt.executeUpdate(); }catch(Exception e){ throw new RuntimeException(e); } } } package cn.itcast.demo; import java.sql.Connection; import java.sql.SQLException; import org.junit.Test; import cn.itcast.jdbc.JdbcUtils; /** * 所有对Connection的操作都在service层进行处理! * 将要处理这个问题,将所有对Connection的操作隐藏起来,需要使用自定义的小工具 * @author Administrator * */ public class Demo1 { /** * 转账方法 * @param from * @param to * @param money */ public void zhuanZhang(String from,String to,double money){ /** * 注意必须使用同一个Connection对象 */ Connection con=null; try{ con=JdbcUtils.getConnection(); con.setAutoCommit(false); AccountDao dao=new AccountDao(); dao.updateBalance(con,from, -money); if(true){ throw new RuntimeException("不好意思"); } dao.updateBalance(con,to, money); con.commit(); }catch(Exception e){ try { con.rollback(); con.close(); } catch (SQLException e1) { } throw new RuntimeException(e); } } @Test public void fun1(){ zhuanZhang("zs","lisi",100); } }