报错如下:
代码如下:
Controller
import com.zwh.service.impl.TimeOutService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/api/timeout") @Slf4j public class DemoController { @Autowired private TimeOutService timeOutService; @GetMapping("/jdbc") public void queryPage() { timeOutService.testAnnotationTransactionalTimeOutWithJdbcTemplate(); } }
service
import com.zwh.dao.StudentDaoWithJdbcTemplate; import lombok.SneakyThrows; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.Resource; @Service public class TimeOutService { @Resource private StudentDaoWithJdbcTemplate studentDaoWithJdbcTemplate; @Autowired private TransactionTemplate transactionTemplate; @Transactional(value = "transactionManager", timeout = 2) public void testAnnotationTransactionalTimeOutWithJdbcTemplate() { try { Thread.sleep(3000); } catch (Exception e) { } studentDaoWithJdbcTemplate.update(); } }
jdbcTemplate
import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.StatementCallback; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.sql.SQLException; import java.sql.Statement; @Component public class StudentDaoWithJdbcTemplate { @Resource private JdbcTemplate jdbcTemplate; public void update() { jdbcTemplate.execute(new StatementCallback<Integer>() { public Integer doInStatement(Statement stmt) throws SQLException, DataAccessException { stmt.execute("update test set name='zhangsan3' where id = 2;"); return 1; } }); } }
数据库表test如下:
使用postman访问:http://localhost:8090/api/timeout/jdbc
原因分析:
我们平时在使用spring框架开发项目时,喜欢用@Transactional
注解声明事务。如上面的:
@Transactional(value = "transactionManager", timeout = 2)
只需在需要使用事务的方法上,使用@Transactional
注解声明一下,该方法通过AOP就自动拥有了事务的功能。
没错,这种做法给我们带来了极大的便利,开发效率更高了。
但也给我们带来了很多隐患,比如大事务的问题。我们一起看看下面的这段代码:
@Transactional(rollbackFor = Throwable.class) public void updateUser(User user) { User oldUser = userMapper.getUserById(user.getId()); if(null != oldUser) { userMapper.update(user); } else { userMapper.insert(user); } sendMq(user); }
这段代码中getUserById方法和sendMq方法,在这个案例中无需使用事务,只有update或insert方法才需要事务。
所以上面这段代码的事务太大了,是整个方法级别的事务。假如sendMq方法是一个非常耗时的操作,则可能会导致整个updateUser方法的事务超时,从而出现大事务问题。
timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。
那么,如何解决这个问题呢?
答:可以使用TransactionTemplate
的编程式事务优化代码。
import com.zwh.dao.StudentDaoWithJdbcTemplate; import lombok.SneakyThrows; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.Resource; @Service public class TimeOutService { @Resource private StudentDaoWithJdbcTemplate studentDaoWithJdbcTemplate; @Autowired private TransactionTemplate transactionTemplate;
public void testAnnotationTransactionalTimeOutWithJdbcTemplate() { try { Thread.sleep(3000); } catch (Exception e) { } transactionTemplate.execute(new TransactionCallbackWithoutResult() { @SneakyThrows protected void doInTransactionWithoutResult(TransactionStatus status) { try { studentDaoWithJdbcTemplate.update(); } catch (Exception e) { status.setRollbackOnly(); throw e; } } }); } }
注意:这里没有了@Transactional(value = "transactionManager", timeout = 2)注解
标签:25,transaction,CST,springframework,public,org,import,annotation From: https://www.cnblogs.com/zwh0910/p/17503573.html