当前位置:Gxlcms > 数据库问题 > JDBC(三)——事务

JDBC(三)——事务

时间:2021-07-01 10:21:17 帮助过:7人阅读

银行转账案例演示

1.需求:一个账号fromAccount向另一个账号toAccount转入money元钱
2.分析:

  • 检查两个账号是否存在,不存在的话,结束转账行为
  • 检查转出账号的里金额是否充足,不充足,结束转账行为,充足的话,进行扣款money元
  • 转入账号进行增加money元
    3.数据准备参考上一篇
    https://www.cnblogs.com/dch-21/p/12920178.html
  1. <code>public class Test {
  2. public static void main(String[] args) {
  3. Scanner scanner=new Scanner(System.in);
  4. System.out.println("请输入出账账号:");
  5. String fromAccount=scanner.nextLine();
  6. System.out.println("请输入进账账号:");
  7. String toAccount=scanner.nextLine();
  8. System.out.println("请输入转账金额:");
  9. double money=scanner.nextDouble();
  10. oneToOne(fromAccount,toAccount,money);
  11. }
  12. public static void oneToOne(String fromAccount,String toAccount,double money){
  13. if(fromAccount==null||fromAccount.length()==0){
  14. System.out.println("输入不正确");
  15. return;
  16. }
  17. if(toAccount==null||toAccount.length()==0){
  18. System.out.println("输入不正确");
  19. return;
  20. }
  21. if(money<0){
  22. System.out.println("输入不正确");
  23. return;
  24. }
  25. Connection connection=null;
  26. PreparedStatement ps=null;
  27. ResultSet resultSet=null;
  28. try{
  29. connection= DBUtil.getConnection();
  30. String sql="select * from bank_account where account_id=?";
  31. ps=connection.prepareStatement(sql);
  32. ps.setString(1,fromAccount);
  33. resultSet = ps.executeQuery();
  34. if(!resultSet.next()){
  35. System.out.println("出账账号有误");
  36. return;
  37. }
  38. double balance = resultSet.getDouble("account_balance");
  39. ps=connection.prepareStatement(sql);
  40. ps.setString(1,toAccount);
  41. resultSet = ps.executeQuery();
  42. if(!resultSet.next()){
  43. System.out.println("进账账号有误");
  44. return;
  45. }
  46. String sql1="update bank_account set account_balance=account_balance+? where account_id=?";
  47. ps=connection.prepareStatement(sql1);
  48. ps.setDouble(1,-money);
  49. ps.setString(2,fromAccount);
  50. int i = ps.executeUpdate();
  51. System.out.println(i+"条数据受到影响");
  52. ps=connection.prepareStatement(sql1);
  53. ps.setDouble(1,money);
  54. ps.setString(2,toAccount);
  55. int j = ps.executeUpdate();
  56. System.out.println(j+"条数据受到影响");
  57. }catch (Exception e){
  58. e.printStackTrace();
  59. }finally {
  60. DBUtil.closeConnection(connection,ps,resultSet);
  61. }
  62. }
  63. }
  64. </code>

输入
技术图片
运行前
技术图片
运行后
技术图片

转账异常演示

在转出账户转出金额之后和转入账户收入金额之前模拟空指针异常
String str = null;
System.out.println(str.length());

  1. <code>package practice;
  2. import practice.jdbc.day03.DBUtil;
  3. import java.io.InputStream;
  4. import java.sql.*;
  5. import java.util.Objects;
  6. import java.util.Properties;
  7. import java.util.Scanner;
  8. /**
  9. * @Author 昊
  10. * @Create 2020/5/19 21:29
  11. * @Description
  12. *
  13. * 模拟银行一对一转账
  14. */
  15. public class Test {
  16. public static void main(String[] args) {
  17. Scanner scanner=new Scanner(System.in);
  18. System.out.println("请输入出账账号:");
  19. String fromAccount=scanner.nextLine();
  20. System.out.println("请输入进账账号:");
  21. String toAccount=scanner.nextLine();
  22. System.out.println("请输入转账金额:");
  23. double money=scanner.nextDouble();
  24. oneToOne(fromAccount,toAccount,money);
  25. }
  26. public static void oneToOne(String fromAccount,String toAccount,double money){
  27. if(fromAccount==null||fromAccount.length()==0){
  28. System.out.println("输入不正确");
  29. return;
  30. }
  31. if(toAccount==null||toAccount.length()==0){
  32. System.out.println("输入不正确");
  33. return;
  34. }
  35. if(money<0){
  36. System.out.println("输入不正确");
  37. return;
  38. }
  39. Connection connection=null;
  40. PreparedStatement ps=null;
  41. ResultSet resultSet=null;
  42. try{
  43. connection= DBUtil.getConnection();
  44. String sql="select * from bank_account where account_id=?";
  45. ps=connection.prepareStatement(sql);
  46. ps.setString(1,fromAccount);
  47. resultSet = ps.executeQuery();
  48. if(!resultSet.next()){
  49. System.out.println("出账账号有误");
  50. return;
  51. }
  52. double balance = resultSet.getDouble("account_balance");
  53. ps=connection.prepareStatement(sql);
  54. ps.setString(1,toAccount);
  55. resultSet = ps.executeQuery();
  56. if(!resultSet.next()){
  57. System.out.println("进账账号有误");
  58. return;
  59. }
  60. String sql1="update bank_account set account_balance=account_balance+? where account_id=?";
  61. ps=connection.prepareStatement(sql1);
  62. ps.setDouble(1,-money);
  63. ps.setString(2,fromAccount);
  64. int i = ps.executeUpdate();
  65. System.out.println(i+"条数据受到影响");
  66. //在转出账户转出金额之后和转入账户收入金额之前模拟空指针异常
  67. String str = null;
  68. System.out.println(str.length());
  69. ps=connection.prepareStatement(sql1);
  70. ps.setDouble(1,money);
  71. ps.setString(2,toAccount);
  72. int j = ps.executeUpdate();
  73. System.out.println(j+"条数据受到影响");
  74. }catch (Exception e){
  75. e.printStackTrace();
  76. }finally {
  77. DBUtil.closeConnection(connection,ps,resultSet);
  78. }
  79. }
  80. }
  81. </code>

加入空指针异常前
技术图片
加入异常后
技术图片
技术图片

解决方案

将手动提交事务改为自动提交,并设置回滚
setAutoCommit(false);
取消事务的自动提交操作,变成手动提交;默认为自动提交;true为自动提交,fals为手动提交
rollback();回滚到事务之初
releaseSavepoint(Savepoint savepoint);回滚到指定位置

事务

事务的特点:
技术图片

  • 默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务。
  • 如果需要在一个事务中包含多条SQL语句,那么需要开启事务和结束事务。
    • 开启事务:start transaction;
    • 结束事务:commit或rollback;

jdbc的事务支持

Connection.setAutoCommit(boolean flag):此方法可以取消事务的自动提交功能,值为false。
Connection.commit():进行事务提交 。
Connection.rollback():进行事务回滚。

  1. <code>public class Test {
  2. public static void main(String[] args) {
  3. Scanner scanner=new Scanner(System.in);
  4. System.out.println("请输入出账账号:");
  5. String fromAccount=scanner.nextLine();
  6. System.out.println("请输入进账账号:");
  7. String toAccount=scanner.nextLine();
  8. System.out.println("请输入转账金额:");
  9. double money=scanner.nextDouble();
  10. oneToOne(fromAccount,toAccount,money);
  11. }
  12. public static void oneToOne(String fromAccount,String toAccount,double money){
  13. if(fromAccount==null||fromAccount.length()==0){
  14. System.out.println("输入不正确");
  15. return;
  16. }
  17. if(toAccount==null||toAccount.length()==0){
  18. System.out.println("输入不正确");
  19. return;
  20. }
  21. if(money<0){
  22. System.out.println("输入不正确");
  23. return;
  24. }
  25. Connection connection=null;
  26. PreparedStatement ps=null;
  27. ResultSet resultSet=null;
  28. try{
  29. connection= DBUtil.getConnection();
  30. //取消事务的自动提交操作,变成手动提交
  31. //默认为自动提交
  32. //true为自动提交,fals为手动提交
  33. connection.setAutoCommit(false);
  34. String sql="select * from bank_account where account_id=?";
  35. ps=connection.prepareStatement(sql);
  36. ps.setString(1,fromAccount);
  37. resultSet = ps.executeQuery();
  38. if(!resultSet.next()){
  39. System.out.println("出账账号有误");
  40. return;
  41. }
  42. double balance = resultSet.getDouble("account_balance");
  43. ps=connection.prepareStatement(sql);
  44. ps.setString(1,toAccount);
  45. resultSet = ps.executeQuery();
  46. if(!resultSet.next()){
  47. System.out.println("进账账号有误");
  48. return;
  49. }
  50. String sql1="update bank_account set account_balance=account_balance+? where account_id=?";
  51. ps=connection.prepareStatement(sql1);
  52. ps.setDouble(1,-money);
  53. ps.setString(2,fromAccount);
  54. ps.executeUpdate();
  55. //在转出账户转出金额之后和转入账户收入金额之前模拟空指针异常
  56. String str = null;
  57. System.out.println(str.length());
  58. ps=connection.prepareStatement(sql1);
  59. ps.setDouble(1,money);
  60. ps.setString(2,toAccount);
  61. ps.executeUpdate();
  62. }catch (Exception e){
  63. e.printStackTrace();
  64. //如果中途出现异常,会回滚到事务之初
  65. try {
  66. connection.rollback();
  67. } catch (SQLException ex) {
  68. ex.printStackTrace();
  69. }
  70. }finally {
  71. DBUtil.closeConnection(connection,ps,resultSet);
  72. }
  73. }
  74. }
  75. </code>

技术图片

JDBC(三)——事务

标签:pack   select   inpu   log   except   state   取消   one   rgs   

人气教程排行