1.首先看一下数据库引擎是否是InnoDB,如果不是改为InnoDB引擎
我这里默认就是InnoDB,所以不是这个异常
2.查看自己代码事务提交的顺序
刚开始我的代码是:
DataSource dataSource = ApplicationContextManager.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
String sql = "xxxx";
{
// 批处理代码这里省略
preparedStatement.executeBatch();
}
// 异常之前提交
connection.commit();
preparedStatement.close();
connection.close();
// 我在这里模拟后续的操作,假设这里有一个异常
int a = 5/0; // 这里理论上会报异常
System.out.println(a);
可以看到上述代码connection.commit()在异常发生之前提交了,并且关闭了连接,所以下面的异常就无法回滚
修改上述代码:
DataSource dataSource = ApplicationContextManager.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
String sql = "xxxx";
{
// 批处理代码这里省略
preparedStatement.executeBatch();
}
// 我在这里模拟后续的操作,假设这里有一个异常
int a = 5/0; // 这里理论上会报异常
System.out.println(a);
// 最后再提交,否则无法回滚
connection.commit();
preparedStatement.close();
connection.close();
总结: 事务的提交和管理都应放到代码段的最后面,防止无法提交