spring 整合mybatis 事务管理 @@Transactiona 的timeout 不起作用

时间:2022-12-26 16:33:43
spring 整合mybatis 事务管理 @Transactional 的timeout 不起作用

问题描述:@Transactiona 配置指定异常 RollbackFor起作用。
                  我觉得@Transactional 注解应该是起作用了。
        可是timeout=2,在@Transactional 注解的方法内使用thread.sleep(5000)

@Transactional(timeout=2)
public void saveService(User user1, User user2) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}  
userMapper.save(user1);
userMapper.save(user2);
}


这是怎么回事????????????????

14 个解决方案

#1


没有人吗。大神呀

#2


你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使

#3


引用 2 楼 lwb314 的回复:
你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使


@Transactional是把 public void saveService(User user1, User user2) 方法设置为一个事务对吧?
我之前用的是spring 的JdbcTemplate 作为Dao。
我设置的

@Transactional(
isolation=Isolation.READ_COMMITTED,
readOnly=false,timeout=2
)  
@Override
public void purchase(String username, String isbn) {

 
 try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 //1.获取数的单价
 int price=bookShopDao.findBookPriceByIsbn(isbn);

//2更新数book 库存
bookShopDao.updateBookStock(isbn);
//更新用户月
bookShopDao.updateUserAccount(username, price);
}

这个timeout就是起作用的。
我现在的想让这public void saveService(User user1, User user2)同样出现TransactionTimedOutException

#4


没有人吗。大神呀 

#5


引用 3 楼 jaedongjuly 的回复:
Quote: 引用 2 楼 lwb314 的回复:

你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使


@Transactional是把 public void saveService(User user1, User user2) 方法设置为一个事务对吧?
我之前用的是spring 的JdbcTemplate 作为Dao。
我设置的

@Transactional(
isolation=Isolation.READ_COMMITTED,
readOnly=false,timeout=2
)  
@Override
public void purchase(String username, String isbn) {

 
 try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 //1.获取数的单价
 int price=bookShopDao.findBookPriceByIsbn(isbn);

//2更新数book 库存
bookShopDao.updateBookStock(isbn);
//更新用户月
bookShopDao.updateUserAccount(username, price);
}

这个timeout就是起作用的。
我现在的想让这public void saveService(User user1, User user2)同样出现TransactionTimedOutException
你把数据库表锁一下,应该就能测试出来你要的效果了

#6


引用 5 楼 lwb314 的回复:
Quote: 引用 3 楼 jaedongjuly 的回复:

Quote: 引用 2 楼 lwb314 的回复:

你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使


@Transactional是把 public void saveService(User user1, User user2) 方法设置为一个事务对吧?
我之前用的是spring 的JdbcTemplate 作为Dao。
我设置的

@Transactional(
isolation=Isolation.READ_COMMITTED,
readOnly=false,timeout=2
)  
@Override
public void purchase(String username, String isbn) {

 
 try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 //1.获取数的单价
 int price=bookShopDao.findBookPriceByIsbn(isbn);

//2更新数book 库存
bookShopDao.updateBookStock(isbn);
//更新用户月
bookShopDao.updateUserAccount(username, price);
}

这个timeout就是起作用的。
我现在的想让这public void saveService(User user1, User user2)同样出现TransactionTimedOutException
你把数据库表锁一下,应该就能测试出来你要的效果了


没有用的,程序一直等待解锁。知道解锁对应的数据表。在等待的时间里都没有出现异常。

#7


引用 6 楼 jaedongjuly 的回复:
Quote: 引用 5 楼 lwb314 的回复:

Quote: 引用 3 楼 jaedongjuly 的回复:

Quote: 引用 2 楼 lwb314 的回复:

你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使


@Transactional是把 public void saveService(User user1, User user2) 方法设置为一个事务对吧?
我之前用的是spring 的JdbcTemplate 作为Dao。
我设置的

@Transactional(
isolation=Isolation.READ_COMMITTED,
readOnly=false,timeout=2
)  
@Override
public void purchase(String username, String isbn) {

 
 try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 //1.获取数的单价
 int price=bookShopDao.findBookPriceByIsbn(isbn);

//2更新数book 库存
bookShopDao.updateBookStock(isbn);
//更新用户月
bookShopDao.updateUserAccount(username, price);
}

这个timeout就是起作用的。
我现在的想让这public void saveService(User user1, User user2)同样出现TransactionTimedOutException
你把数据库表锁一下,应该就能测试出来你要的效果了


没有用的,程序一直等待解锁。知道解锁对应的数据表。在等待的时间里都没有出现异常。
那就是你的超时设置没好使啊

#8


引用 7 楼 lwb314 的回复:
Quote: 引用 6 楼 jaedongjuly 的回复:

Quote: 引用 5 楼 lwb314 的回复:

Quote: 引用 3 楼 jaedongjuly 的回复:

Quote: 引用 2 楼 lwb314 的回复:

你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使


@Transactional是把 public void saveService(User user1, User user2) 方法设置为一个事务对吧?
我之前用的是spring 的JdbcTemplate 作为Dao。
我设置的

@Transactional(
isolation=Isolation.READ_COMMITTED,
readOnly=false,timeout=2
)  
@Override
public void purchase(String username, String isbn) {

 
 try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 //1.获取数的单价
 int price=bookShopDao.findBookPriceByIsbn(isbn);

//2更新数book 库存
bookShopDao.updateBookStock(isbn);
//更新用户月
bookShopDao.updateUserAccount(username, price);
}

这个timeout就是起作用的。
我现在的想让这public void saveService(User user1, User user2)同样出现TransactionTimedOutException
你把数据库表锁一下,应该就能测试出来你要的效果了


没有用的,程序一直等待解锁。知道解锁对应的数据表。在等待的时间里都没有出现异常。
那就是你的超时设置没好使啊


那我应该怎么设置呀???
@Transactional(timeout=2)
 public void saveService(User user1, User user2)
方法上设置的是2秒。
我锁表的时间是30秒,
之后我解表。
数据一下就插进来了。
我刚学的。不好意思。

#9


没有人吗。大神呀  

#10


没设置过超时时间,帮不了你了

#11


spring的org.springframework.jdbc.datasource.DataSourceTransactionManager 只对jdbcTemplate生效
mybatis的超时时间针对statementHandler

#12


@Intercepts({
        @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),
        @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class}),
        @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})})
public class MybatisTransactionTimeoutInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Statement stmt = (Statement) invocation.getArgs()[0];
        Collection<Object> values = TransactionSynchronizationManager.getResourceMap().values();
        if (values.size() > 0) {
            for (Object obj : values) {
                if (obj != null && obj instanceof ConnectionHolder) {
                    ConnectionHolder holder = (ConnectionHolder) obj;
                    if (holder.hasTimeout()) {
                        int queryTimeOut = holder.getTimeToLiveInSeconds();
                        if (stmt.getQueryTimeout() != 0) {
                            queryTimeOut = queryTimeOut < stmt.getQueryTimeout() ? queryTimeOut : stmt.getQueryTimeout();
                        }
                        stmt.setQueryTimeout(queryTimeOut);
                    }
                    break;
                }
            }
        }

        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

#13


还有就是需要看数据库表的类型 mysql 中 InnoDB 类型的表才支持事物

#14


超时时间你没设置啊

#1


没有人吗。大神呀

#2


你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使

#3


引用 2 楼 lwb314 的回复:
你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使


@Transactional是把 public void saveService(User user1, User user2) 方法设置为一个事务对吧?
我之前用的是spring 的JdbcTemplate 作为Dao。
我设置的

@Transactional(
isolation=Isolation.READ_COMMITTED,
readOnly=false,timeout=2
)  
@Override
public void purchase(String username, String isbn) {

 
 try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 //1.获取数的单价
 int price=bookShopDao.findBookPriceByIsbn(isbn);

//2更新数book 库存
bookShopDao.updateBookStock(isbn);
//更新用户月
bookShopDao.updateUserAccount(username, price);
}

这个timeout就是起作用的。
我现在的想让这public void saveService(User user1, User user2)同样出现TransactionTimedOutException

#4


没有人吗。大神呀 

#5


引用 3 楼 jaedongjuly 的回复:
Quote: 引用 2 楼 lwb314 的回复:

你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使


@Transactional是把 public void saveService(User user1, User user2) 方法设置为一个事务对吧?
我之前用的是spring 的JdbcTemplate 作为Dao。
我设置的

@Transactional(
isolation=Isolation.READ_COMMITTED,
readOnly=false,timeout=2
)  
@Override
public void purchase(String username, String isbn) {

 
 try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 //1.获取数的单价
 int price=bookShopDao.findBookPriceByIsbn(isbn);

//2更新数book 库存
bookShopDao.updateBookStock(isbn);
//更新用户月
bookShopDao.updateUserAccount(username, price);
}

这个timeout就是起作用的。
我现在的想让这public void saveService(User user1, User user2)同样出现TransactionTimedOutException
你把数据库表锁一下,应该就能测试出来你要的效果了

#6


引用 5 楼 lwb314 的回复:
Quote: 引用 3 楼 jaedongjuly 的回复:

Quote: 引用 2 楼 lwb314 的回复:

你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使


@Transactional是把 public void saveService(User user1, User user2) 方法设置为一个事务对吧?
我之前用的是spring 的JdbcTemplate 作为Dao。
我设置的

@Transactional(
isolation=Isolation.READ_COMMITTED,
readOnly=false,timeout=2
)  
@Override
public void purchase(String username, String isbn) {

 
 try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 //1.获取数的单价
 int price=bookShopDao.findBookPriceByIsbn(isbn);

//2更新数book 库存
bookShopDao.updateBookStock(isbn);
//更新用户月
bookShopDao.updateUserAccount(username, price);
}

这个timeout就是起作用的。
我现在的想让这public void saveService(User user1, User user2)同样出现TransactionTimedOutException
你把数据库表锁一下,应该就能测试出来你要的效果了


没有用的,程序一直等待解锁。知道解锁对应的数据表。在等待的时间里都没有出现异常。

#7


引用 6 楼 jaedongjuly 的回复:
Quote: 引用 5 楼 lwb314 的回复:

Quote: 引用 3 楼 jaedongjuly 的回复:

Quote: 引用 2 楼 lwb314 的回复:

你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使


@Transactional是把 public void saveService(User user1, User user2) 方法设置为一个事务对吧?
我之前用的是spring 的JdbcTemplate 作为Dao。
我设置的

@Transactional(
isolation=Isolation.READ_COMMITTED,
readOnly=false,timeout=2
)  
@Override
public void purchase(String username, String isbn) {

 
 try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 //1.获取数的单价
 int price=bookShopDao.findBookPriceByIsbn(isbn);

//2更新数book 库存
bookShopDao.updateBookStock(isbn);
//更新用户月
bookShopDao.updateUserAccount(username, price);
}

这个timeout就是起作用的。
我现在的想让这public void saveService(User user1, User user2)同样出现TransactionTimedOutException
你把数据库表锁一下,应该就能测试出来你要的效果了


没有用的,程序一直等待解锁。知道解锁对应的数据表。在等待的时间里都没有出现异常。
那就是你的超时设置没好使啊

#8


引用 7 楼 lwb314 的回复:
Quote: 引用 6 楼 jaedongjuly 的回复:

Quote: 引用 5 楼 lwb314 的回复:

Quote: 引用 3 楼 jaedongjuly 的回复:

Quote: 引用 2 楼 lwb314 的回复:

你都说了是设置的mybaties的超时时间,再看你的程序

 try {
            Thread.sleep(5000);//程序就停这里的根本不会往下走
        } catch (InterruptedException e) {
            e.printStackTrace();
        }                 
        userMapper.save(user1); //这里才开始走mybaties          
        userMapper.save(user2);

所以说你的那个sleep并没有什么卵用,而不是超时时间没好使


@Transactional是把 public void saveService(User user1, User user2) 方法设置为一个事务对吧?
我之前用的是spring 的JdbcTemplate 作为Dao。
我设置的

@Transactional(
isolation=Isolation.READ_COMMITTED,
readOnly=false,timeout=2
)  
@Override
public void purchase(String username, String isbn) {

 
 try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
 
 //1.获取数的单价
 int price=bookShopDao.findBookPriceByIsbn(isbn);

//2更新数book 库存
bookShopDao.updateBookStock(isbn);
//更新用户月
bookShopDao.updateUserAccount(username, price);
}

这个timeout就是起作用的。
我现在的想让这public void saveService(User user1, User user2)同样出现TransactionTimedOutException
你把数据库表锁一下,应该就能测试出来你要的效果了


没有用的,程序一直等待解锁。知道解锁对应的数据表。在等待的时间里都没有出现异常。
那就是你的超时设置没好使啊


那我应该怎么设置呀???
@Transactional(timeout=2)
 public void saveService(User user1, User user2)
方法上设置的是2秒。
我锁表的时间是30秒,
之后我解表。
数据一下就插进来了。
我刚学的。不好意思。

#9


没有人吗。大神呀  

#10


没设置过超时时间,帮不了你了

#11


spring的org.springframework.jdbc.datasource.DataSourceTransactionManager 只对jdbcTemplate生效
mybatis的超时时间针对statementHandler

#12


@Intercepts({
        @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),
        @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class}),
        @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})})
public class MybatisTransactionTimeoutInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Statement stmt = (Statement) invocation.getArgs()[0];
        Collection<Object> values = TransactionSynchronizationManager.getResourceMap().values();
        if (values.size() > 0) {
            for (Object obj : values) {
                if (obj != null && obj instanceof ConnectionHolder) {
                    ConnectionHolder holder = (ConnectionHolder) obj;
                    if (holder.hasTimeout()) {
                        int queryTimeOut = holder.getTimeToLiveInSeconds();
                        if (stmt.getQueryTimeout() != 0) {
                            queryTimeOut = queryTimeOut < stmt.getQueryTimeout() ? queryTimeOut : stmt.getQueryTimeout();
                        }
                        stmt.setQueryTimeout(queryTimeOut);
                    }
                    break;
                }
            }
        }

        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

#13


还有就是需要看数据库表的类型 mysql 中 InnoDB 类型的表才支持事物

#14


超时时间你没设置啊