参考:数据库事务 最全详解-----_出走半生归来仍是少年的博客-CSDN博客_数据库事务
- Connection.setAutoCommit(false);//设置自动提交为false
- Connection.rollback();//回滚事务(rollback)
- Connection.commit();//提交事务(commit)
-
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import me.gacl.utils.JdbcUtils; import org.junit.Test; /** * @ClassName: TransactionDemo1 * @Description: * JDBC中使用事务来模似转帐 create table account( id int primary key auto_increment, name varchar(40), money float ); insert into account(name,money) values('A',1000); insert into account(name,money) values('B',1000); insert into account(name,money) values('C',1000); * */ public class TransactionDemo1 { /** * @Method: testTransaction1 * @Description: 模拟转账成功时的业务场景 * */ @Test public void testTransaction1(){ Connection conn = null; PreparedStatement st = null; ResultSet rs = null; 39 40 try{ 41 conn = JdbcUtils.getConnection(); 42 conn.setAutoCommit(false);//通知数据库开启事务(start transaction) 43 String sql1 = "update account set money=money-100 where name='A'"; 44 st = conn.prepareStatement(sql1); 45 st.executeUpdate(); 46 String sql2 = "update account set money=money+100 where name='B'"; 47 st = conn.prepareStatement(sql2); 48 st.executeUpdate(); 49 conn.commit();//上面的两条SQL执行Update语句成功之后就通知数据库提交事务(commit) 50 System.out.println("成功!!!"); //log4j 51 }catch (Exception e) { 52 e.printStackTrace(); 53 }finally{ 54 JdbcUtils.release(conn, st, rs); 55 } 56 } 57 58 /** 59 * @Method: testTransaction1 60 * @Description: 模拟转账过程中出现异常导致有一部分SQL执行失败后让数据库自动回滚事务 62 * 63 */ 64 @Test 65 public void testTransaction2(){ 66 Connection conn = null; 67 PreparedStatement st = null; 68 ResultSet rs = null; 69 70 try{ 71 conn = JdbcUtils.getConnection(); 72 conn.setAutoCommit(false);//通知数据库开启事务(start transaction) 73 String sql1 = "update account set money=money-100 where name='A'"; 74 st = conn.prepareStatement(sql1); 75 st.executeUpdate(); 76 //用这句代码模拟执行完SQL1之后程序出现了异常而导致后面的SQL无法正常执行,事务也无法正常提交,此时数据库会自动执行回滚操作 77 int x = 1/0; 78 String sql2 = "update account set money=money+100 where name='B'"; 79 st = conn.prepareStatement(sql2); 80 st.executeUpdate(); 81 conn.commit();//上面的两条SQL执行Update语句成功之后就通知数据库提交事务(commit) 82 System.out.println("成功!!!"); 83 }catch (Exception e) { 84 e.printStackTrace(); 85 }finally{ 86 JdbcUtils.release(conn, st, rs); 87 } 88 } 89 90 /** 91 * @Method: testTransaction1 92 * @Description: 模拟转账过程中出现异常导致有一部分SQL执行失败时手动通知数据库回滚事务 94 * 95 */ 96 @Test 97 public void testTransaction3(){ 98 Connection conn = null; 99 PreparedStatement st = null; 100 ResultSet rs = null; 101 102 try{ 103 conn = JdbcUtils.getConnection(); 104 conn.setAutoCommit(false);//通知数据库开启事务(start transaction) 105 String sql1 = "update account set money=money-100 where name='A'"; 106 st = conn.prepareStatement(sql1); 107 st.executeUpdate(); 108 //用这句代码模拟执行完SQL1之后程序出现了异常而导致后面的SQL无法正常执行,事务也无法正常提交 109 int x = 1/0; 110 String sql2 = "update account set money=money+100 where name='B'"; 111 st = conn.prepareStatement(sql2); 112 st.executeUpdate(); 113 conn.commit();//上面的两条SQL执行Update语句成功之后就通知数据库提交事务(commit) 114 System.out.println("成功!!!"); 115 }catch (Exception e) { 116 try { 117 //捕获到异常之后手动通知数据库执行回滚事务的操作 118 conn.rollback(); 119 } catch (SQLException e1) { 120 e1.printStackTrace(); 121 } 122 e.printStackTrace(); 123 }finally{ 124 JdbcUtils.release(conn, st, rs); 125 } 126 } 127 }
设置回滚点
-
Savepoint sp = conn.setSavepoint();
-
Conn.rollback(sp);
-
Conn.commit();//回滚后必须通知数据库提交事务
-
3 import java.sql.Connection; 4 import java.sql.PreparedStatement; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Savepoint; 8 9 import me.gacl.utils.JdbcUtils; 10 import org.junit.Test; 11 12 /** 13 * @ClassName: TransactionDemo1 14 * @Description: 15 * JDBC中使用事务来模似转帐 16 create table account( 17 id int primary key auto_increment, 18 name varchar(40), 19 money float 20 ); 21 insert into account(name,money) values('A',1000); 22 insert into account(name,money) values('B',1000); 23 insert into account(name,money) values('C',1000); 24 * @author: 孤傲苍狼 25 * @date: 2014-9-22 下午11:16:17 26 * 27 */ 28 public class TransactionDemo2 { 29 30 /** 31 * @Method: testTransaction1 32 * @Description: 模拟转账成功时的业务场景 34 * 35 */ 36 @Test 37 public void testTransaction1(){ 38 Connection conn = null; 39 PreparedStatement st = null; 40 ResultSet rs = null; 41 Savepoint sp = null; 42 43 try{ 44 conn = JdbcUtils.getConnection(); 45 conn.setAutoCommit(false);//通知数据库开启事务(start transaction) 46 47 String sql1 = "update account set money=money-100 where name='A'"; 48 st = conn.prepareStatement(sql1); 49 st.executeUpdate(); 50 51 //设置事务回滚点 52 sp = conn.setSavepoint(); 53 54 String sql2 = "update account set money=money+100 where name='B'"; 55 st = conn.prepareStatement(sql2); 56 st.executeUpdate(); 57 58 //程序执行到这里出现异常,后面的sql3语句执行将会中断 59 int x = 1/0; 60 61 String sql3 = "update account set money=money+100 where name='C'"; 62 st = conn.prepareStatement(sql3); 63 st.executeUpdate(); 64 65 conn.commit(); 66 67 }catch (Exception e) { 68 try { 69 /** 70 * 我们在上面向数据库发送了3条update语句, 71 * sql3语句由于程序出现异常导致无法正常执行,数据库事务而已无法正常提交, 72 * 由于设置的事务回滚点是在sql1语句正常执行完成之后,sql2语句正常执行之前, 73 * 那么通知数据库回滚事务时,不会回滚sql1执行的update操作 74 * 只会回滚到sql2执行的update操作,也就是说,上面的三条update语句中,sql1这条语句的修改操作起作用了 75 * sql2的修改操作由于事务回滚没有起作用,sql3由于程序异常没有机会执行 76 */ 77 conn.rollback(sp);//回滚到设置的事务回滚点 78 //回滚了要记得通知数据库提交事务 79 conn.commit(); 80 } catch (SQLException e1) { 81 e1.printStackTrace(); 82 } 83 e.printStackTrace(); 84 }finally{ 85 JdbcUtils.release(conn, st, rs); 86 } 87 } 88 }