PDA

View Full Version : ثبت همزمان شماره فاکتور



mehregan
یک شنبه 14 بهمن 1386, 13:40 عصر
سلام
در یک سیستم فروش کالا، برای ثبت فاکتور از sp زیر استفاده میکنیم.
به یک مشکل عجیب برخوردم و آن اینکه چند فاکتور با شماره تکراری ثبت شده است.
فاکتورها پشت سرهم و از روی 2 سیستم مختلف ثبت شده است.
اشکال از چی میتونه باشه؟

ممنون






CREATE PROCEDURE [dbo].[factorInsert]
@ID int OUTPUT,
@FacSno int OUTPUT,
@FacDate int = 0,
@FacDiscount decimal = NULL,
@FacAmountTotal decimal = 0,
@FacIsRevoke bit = 0,
@userId int = NULL,
@DayWeek int
AS
DECLARE @Err AS Int
BEGIN TRANSACTION
SELECT @FacSno = ISNULL(MAX(FacSno),0) + 1 FROM acc_factor WHERE FacIsRevoke = @FacIsRevoke
INSERT INTO [dbo].[acc_factor] (
[FacSno],
[FacDate],
[FacDiscount],
[FacAmountTotal],
[FacIsRevoke],
[userId],
[DayWeek]
)
VALUES(
@FacSno,
@FacDate,
@FacDiscount,
@FacAmountTotal,
@FacIsRevoke,
@userId,
@DayWeek
)
SET @Err = @@ERROR
IF @Err = 0
BEGIN
COMMIT TRANSACTION
SET @ID = @@IDENTITY
END
ELSE
BEGIN
ROLLBACK TRANSACTION
IF @Err=50000
BEGIN
RAISERROR('امکان درج رکورد وجود ندارد',16,1)
END
ELSE
BEGIN
RETURN @Err
END
END
GO

JAFO_IRAN
یک شنبه 14 بهمن 1386, 16:19 عصر
سلام

البته مطمئن نیستم که کنترل همزمانی درست انجام بشه - بستگی به settingها داره - اما با توجه به اینکه داخل Transaction کد نوشتید احتمالا مشکل همزمانی نباشه.

ممکنه که این sp رو دو بار با مقادیر مختلف FacIsRevoke اجرا کرده باشید که در اون صورت، مقداری که از Max بدست میاد ممکنه برای دو فاکتور (بر حسب Revoke بودن) تکراری بشن...

ارادت

رضا عربلو
یک شنبه 14 بهمن 1386, 19:49 عصر
کنترل همزمانی درست انجام نشده(من خودم قبلاً این اشتباه را مرتکب شده بودم).
بهتره شماره ردیف را در یک جدول دیگر ذخیره کنید که آخرین شماره را در خود نگه می دارد بعد در ابتدای تراکنشتان مقدار جدول رو با xlock بخونین و Update کنین تا در آن واحد، تنها یک کاربر بتونه مقداری رو از جدول بخونه. با توجه به اینکه چنین جدولی تنها یک فیلد و یک رکورد داره، مشکل همزمانی در فراخوانی SP نخواهید داشت چون کار در چند هزارم ثانیه انجام میشه

حمیدرضاصادقیان
یک شنبه 14 بهمن 1386, 20:36 عصر
راهی هم که بنده دارم انجام میدم و مشکلی هم نداره اینه که وقتی در برنامه شبکه کاربران شروع به زدن فاکتور میکنند به هرکدوم آخرین شماره رو میده و چون جایی ثبت نشده هر دو یک شماره دارند.تاحالا هیچ رکوردی هم قفل نشده است.وقتی که میخواد فاکتور رو ذخیره کند دوباره مقدار رو چک میکنم اگر تکراری بود آخرین شماره رو بهش اختصاص میدم.
با این روش مشکلم حل شد .سرعتش هم خیلی خوبه.

mehregan
یک شنبه 14 بهمن 1386, 23:54 عصر
سلام
در این سیستم صندوقدارها شروع به زدن فاکتور میکنند و موقع ذخیره شماره اختصاص داده میشود و فاکتور ذخیره میشود.
از FacIsRevoke هم برای تعیین نوع فاکتور فروش یا برگشت از فروش استفاده میشود که بیش از 90درصد همیشه 0 میباشد. بنابراین از این بابت تداخلی نیست.
مشکل از همزمانی این عمل میباشد. در 250 هزار فاکتور صادره، فقط 5 مورد با این مشکل مواجه شده است.
با ایجاد ایندکس روی این دو فیلد میشه جلوی تکراری بودن را بگیرم ولی دنبال علت به وجود آمدن این مشکل هستم.

SYNDROME
دوشنبه 15 بهمن 1386, 07:36 صبح
فیلد فاکتور را کلید بگیرید تا اگر به طور همزمان هم عمل ثبت انجام شده فقط یکی ثبت شود و به کاربر دیگر پیغام دهد که دوباره دکمه ثبت را کلیک کند و با شماره جدید عمل ثبت را انجام دهد.
موفق باشید

AminSobati
دوشنبه 15 بهمن 1386, 07:52 صبح
دوست عزیزم،
max گرفتن روی فیلد، هم میتونه به مرور کار رو کند کنه (که البته با داشتن ایندکس معضل کندی قابل حله) و هم به دلیل اینکه چند کاربر به صورت همزمان میتونن max بگیرن، همونطور که دیدین مستعد تولید id تکراری هست. به اعتقاد من یا از فیلد identity استفاده کنین، یا از روش آقای عربلو در پست شماره 3. اگر ترتیب منظم شماره ها مد نظر هست، حتما Error Handling مناسب انجام بدین تا idهایی که احیانا به هر دلیلی ورودشون fail میشه، جایی ثبت بشن تا مجددا مورد استفاده قرار بگیرن