MyBatis 事務回滾的實際案例通常涉及到數據庫操作的異常處理。當一個事務中的操作出現異常時,我們需要確保整個事務能夠回滾,以保持數據的一致性。以下是一個簡單的實際案例:
假設我們有一個用戶管理系統,其中包括用戶表(user)和訂單表(order)。當用戶下訂單時,我們需要先檢查用戶是否存在,然后創建訂單。如果在這個過程中出現任何異常,我們需要回滾事務。
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) NOT NULL UNIQUE
);
CREATE TABLE order (
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT NOT NULL,
product VARCHAR(255) NOT NULL,
FOREIGN KEY (user_id) REFERENCES user(id)
);
public interface UserMapper {
User getUserById(int id);
}
public interface OrderMapper {
int insertOrder(Order order);
}
UserMapper.xml:
<mapper namespace="com.example.mapper.UserMapper">
<select id="getUserById" resultType="com.example.entity.User">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>
OrderMapper.xml:
<mapper namespace="com.example.mapper.OrderMapper">
<insert id="insertOrder" parameterType="com.example.entity.Order">
INSERT INTO `order` (`user_id`, `product`) VALUES (#{userId}, #{product})
</insert>
</mapper>
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private OrderMapper orderMapper;
@Transactional(rollbackFor = Exception.class)
public void createOrder(int userId, String product) {
try {
User user = userMapper.getUserById(userId);
if (user == null) {
throw new RuntimeException("User not found");
}
Order order = new Order();
order.setUserId(userId);
order.setProduct(product);
orderMapper.insertOrder(order);
} catch (Exception e) {
throw e;
}
}
}
在這個例子中,我們使用 @Transactional
注解來標注 createOrder
方法,表示這個方法是一個事務。當方法內拋出異常時,事務會自動回滾。在 createOrder
方法中,我們首先檢查用戶是否存在,如果不存在則拋出一個運行時異常。如果用戶存在,我們創建一個新的訂單并插入到數據庫中。如果在創建訂單的過程中出現任何異常,事務會自動回滾,保證數據的一致性。