就是功能实现
例:Account类要求编写业务逻辑层AccountServiceImpl类实现一个转账功能
先定义DBUtils类封装数据库连接代码、定义Account类、定义PersonDao类提供增删改查方法
public class AccountServiceImpl{
public static void transfer(int fromId,String pwd,int toId,double money){
//判断转账的用户id和密码是否正确
//定义DBUtils类封装数据库连接代码、定义Account类、定义PersonDao类提供增删改查方法
PersonDao personDao = new PersonDao();
Account account = null;
account = personDao.select(fromid);
if(account==null){
throw new RuntimeException("卡号错误");
}
if(account.getPassword()!=pwd){
throw new RuntimeException("密码错误");
}
Account account1 = null;
account1 = personDao.select(toId);
if(account2==null){
throw new RuntimeException("对方卡号不存在");
)
if(account.getBalance()
以上代码在出差后不可逆,所以需要事务控制,当报错后,对数据库的内容修改回到初始态
Service层实现控制事务:(案例中余额减少出现异常情况)
获得连接对象:
设置当前事务的自动提交为手动提交,开启事务
connection.setAutoCommit(false);//false参数即关闭自动提交
connection.commit();//提交事务
connection.rollback();//回滚
关闭connection问题:
解决方法1:传递connection
缺点:不能复用,容易造成接口污染
解决方法2:ThreadLocal:
单线程中,存储一个共享值
线程拥有一个类似Map的属性,键值对结构
一个共享同一个ThreadLocal,在整个流程中任一环节可以存值或取值。
利用ThreadLocal重写DBUtils并封装事务
定义ThreadLocal threadLocal = new ThreadLocal<>();
利用ThreadLocal类的get()和set()方法,如果connection==null,则threadLocal.set(DriverManager.getConnection)
使我们拿到的connection为同一个
把Dao层的增删改查方法中的closeAll()方法中的形参Connection connection全部设置为空
public class DBUtils{
public static final Properties PROPERTIES = new Proerties();
private static ThreadLocal threadLocal = new ThreadLocal<>();
static{
InputStream is = DBUtils.class.getResourceAsStream("database.properties");
PROPERTIES.load(is);
class.forName(PROPERTIES.getProperties("driver"));
}
public static Connection getConnection(){
Connection connection = threadLocal.get();
if(conncetion==null){
connection = DriverManager.getConnection(PROPERTIES.getProperties("url"),PROPRETIES.getProperties("user"),PROPERTIES.getProperties("password"));
threadLocal.set(connection);
}
return connection;
}
public static void begin(){
Connection connection = getConnection();
connection.setAutoCommit(false);
}
public static void commit(){
Connection connection = getConnection();
connection.commit();
}
public static void rollback(){
Connection connection = getConnection();
connection.rollback();
}
//把Dao层的增删改查方法中的closeAll()方法中的形参Connection connection全部设置为空
public static void closeAll(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){
if(connection!=null){
try {
connection.close();
threadLocal.remove();//关闭连接后,移除connection对象
} catch (SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
把重写过的DBUtils控制事务方法添加到Service业务逻辑层的方法中
DBUtils.begin();//写在transfar()方法的开头
DBUtils.commit();//写在transfar()方法结尾
DBUtils.rollback;//写在trycatch中的catch代码里面



