我有一个表,其中有一个列,该列tripNumber不应重复。
我知道,我可以更改表并创建该列,unique但是由于某种原因,我无法更改该表,因为它已经在生产中。因此,我编写了以下触发器,基本上可以完成相同的操作。
USE [cst_abc]
GO
/****** Object: Trigger [dbo].[checkTripNumber] Script Date: 12/21/2019 18:37:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE trigger [dbo].[checkTripNumber] on [dbo].[tripDetails]
instead of insert
as
begin
if exists(select * from [dbo].[tripDetails] where tripNumber = (select [tripNumber] from inserted i))
RAISERROR ('Trip is already there.',15,0);
else
INSERT INTO [cst_abc].[dbo].[tripDetails]
([tripNumber]
,[noW]
,[EndTime]
,[someText]
,[totalInput]
,[totalOutput]
,[Difference]
,[start]
,[end]
,[StartTime]
,[EndTime]
,[serverSync])
SELECT[tripNumber],[noW],[EndTime]
,[someText]
,[totalInput]
,[totalOutput]
,[Difference]
,[start]
,[end]
,[StartTime]
,[EndTime]
,[serverSync] from inserted i
end
GO
它确实按预期工作。我写了一个小的Java代码,它基本上启动了一个新线程并尝试插入行。我要做的是先检查行程是否存在,如果是,则不执行任何操作,否则插入具有特定ID的新行。
public static void startThread()
{
new Thread(() -> {
try {
showTimeInMilli("FuncA");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
showTimeInMilli("FuncB");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}).start();
}
public static void showTimeInMilli(String name) throws SQLException
{
System.out.println("called from "+name +"Current time is "+System.currentTimeMillis());
if(checkTripNumber(1))
{
System.out.println("called from "+name +" and trip exists.");
}
else
{
System.out.println("called from "+name +" and inserting new row.");
SqlUtil.startNewTrip(1,7,"ap1","2019-06-18 07:06:00",5,1576631560);
}
}
这里要注意的一点是,该触发器即startTrip可以从多个源触发,并且我已经看到大多数时候它是同时触发的(epoch例如,我从两个源中准确地存储了它被触发的时间1576934304)
问题
在预期的10倍中有9倍,即它不让新行添加,但有时会添加重复行tripNumber。非常感谢您的帮助。
上面的Java代码的理想日志是:
called from FuncACurrent time is 1576933097423
called from FuncBCurrent time is 1576933097423
td before sendig false
called from FuncB and inserting new row.
td before sendig false
called from FuncA and inserting new row.
com.microsoft.sqlserver.jdbc.SQLServerException: Trip is already there.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:217)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1655)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:440)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:385)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7505)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:2445)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:191)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:166)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.execute(SQLServerPreparedStatement.java:367)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.execute(HikariProxyPreparedStatement.java)
at database.SqlUtil.startNewTrip(SqlUtil.java:45)
at database.Hikari.showTimeInMilli(Hikari.java:122)
at database.Hikari.lambda$0(Hikari.java:44)
at java.lang.Thread.run(Unknown Source)
SQL Exception2 com.microsoft.sqlserver.jdbc.SQLServerException: Trip is already there.
意外的日志是:
called from FuncACurrent time is 1576933097323
called from FuncBCurrent time is 1576933097323
td before sendig false
called from FuncB and inserting new row.
td before sendig false
called from FuncA and inserting new row.
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。