grails服务使用mysql进行死锁

时间:2013-03-07 15:00:17

标签: mysql grails service locking acl

我正在尝试将一长串文件添加到mysql中,并使用带有grails的spring ACL服务来附加权限。 所以,在我的控制器里我有:

Files.withTransaction {
            Files file = new Files(dataStore:ds,created:new Date(),path:target,name:fileName,contentType:contentType,contentLength:contentLength,isFolder:false).save(flush:true)
            file = Files.lock(file.id)
            filesService.addPermission(file, username ,BasePermission.ADMINISTRATION)
        }

我不用担心Files域对象,它支持大量数据,(特别是因为我在mysql中禁用了版本控制),问题出在使用aclUtilService的filesService上,

@Transactional
    @PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER') or hasRole('ROLE_GROUP_OWNER')")
    def addPermission(Files f, String username,Permission permission) {
        aclUtilService.addPermission f,username,permission
    }

随机我有以下死锁(optmistic?)错误:

  

试图锁定时发现死锁;尝试重新启动事务。   Stacktrace如下:   com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException:   试图锁定时发现死锁;尝试重新启动交易   com.mysql.jdbc.Util.handleNewInstance(Util.java:406)at at   com.mysql.jdbc.Util.getInstance(Util.java:381)at   com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1045)at at   com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)at at   com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558)at at   com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490)at at   com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)at at   com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)at at   com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648)at at   com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077)     在   com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2362)     在   com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2280)     在   com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2265)     在   org.grails.plugins.springsecurity.service.acl.AclService.save(AclService.groovy:330)     在   org.grails.plugins.springsecurity.service.acl.AclService.createEntries(AclService.groovy:198)     在   org.grails.plugins.springsecurity.service.acl.AclService.updateAcl(AclService.groovy:176)     在   GrailsMelodyGrailsPlugin $ _closure5_closure18_closure19.doCall(GrailsMelodyGrailsPlugin.groovy:170)     在   org.grails.plugins.springsecurity.service.acl.AclUtilService.addPermission(AclUtilService.groovy:90)     在   org.grails.plugins.springsecurity.service.acl.AclUtilService.addPermission(AclUtilService.groovy:67)     在   GrailsMelodyGrailsPlugin $ _closure5_closure18_closure19.doCall(GrailsMelodyGrailsPlugin.groovy:170)     在   xxxxxxxxxxxxx.FilesService.addPermission(FilesService.groovy:34)     在   GrailsMelodyGrailsPlugin $ _closure5_closure18_closure19.doCall(GrailsMelodyGrailsPlugin.groovy:170)     在   xxxxxxxxxxxxxQuantumController $ _uploadToS3_closure1 $$ ENzPdDAW.doCall(QuantumController.groovy:87)     在   org.grails.datastore.gorm.GormStaticApi.withTransaction(GormStaticApi.groovy:686)     在   xxxxxxxxxxxxx.QuantumController $$ ENzPdDAW.uploadToS3(QuantumController.groovy:84)     在   grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:195)     在   grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)     在net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:149)at   net.bull.javamelody.JdbcWrapper $ DelegatingInvocationHandler.invoke(JdbcWrapper.java:259)     在   net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:202)     在   net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:175)     在   java.util.concurrent.ThreadPoolExecutor中的$ Worker.runTask(ThreadPoolExecutor.java:895)     在   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:918)     在java.lang.Thread.run(Thread.java:680)

请帮忙吗?

1 个答案:

答案 0 :(得分:0)

只是将事务封装在控制器中并在服务中使用@Transactional来解决问题:

Files.withTransaction {
                    Files file = new Files(
...
                    if (file.validate()) {
                        file.save()
                        filesService.addPermission(file,username,BasePermission.ADMINISTRATION)

...}
}