Add-Migration Initial Update-Database
String or binary data would be truncated. The statement has been terminated.
// Delete DELETE FROM MyTable WHERE LEN(SomeProp1) > 3 // OR // Truncate UPDATE MyTable SET SomeProp1 = LEFT(SomeProp1, 3) WHERE LEN(SomeProp1) > 3
We are thrilled to announce that the webhint browser extension has moved from beta to its v1 release and is now available for Insider builds of Microsoft Edge, as well as for Chrome and Firefox!
عموما هنگام نصب SQL Server ، پیش و پس از آن، بهتر است موارد زیر جهت بالا بردن کیفیت و کارآیی سرور، رعایت شوند:
1- پیش فرضهای نصب SQL Server در مورد محل قرارگیری فایلهای دیتا و لاگ و غیره صحیح نیست. هر کدام باید در یک درایو مجزا مسیر دهی شوند برای مثال:
Data drive D:
Transaction Log drive E:
TempDB drive F:
Backup drive G:
همچنین وجود این مسیرهای مشخص و پیش فرض و آگاهی از سطوح دسترسی مورد نیاز آنها، از سر دردهای بعدی جلوگیری خواهد کرد. برای مثال : انتقال فایلهای دیتابیس اس کیوال سرور 2008
2- پس از رعایت مورد 1 ، نوبت به تنظیمات آنتی ویروس نصب شده روی سرور است. این پوشههای ویژه را که جهت فایلهای دیتا و لاگ و غیره بر روی درایوهای مختلف معرفی کردهاید یا خواهید نمود، باید از تنظیمات آنتی ویروس شما Exclude شوند. همچنین در حالت کلی فایلهایی با پسوندهای LDF/MDF/NDF باید جزو فایلهای صرفنظر شونده از دید آنتی ویروس شما معرفی گردند.
این مورد علاوه بر بالا بردن کارآیی SQL Server ، در حین Boot سیستم نیز تاثیر گذار است. گاها دیده شده است که آنتی ویروسها این فایلهای حجیم را در حین راه اندازی اولیه سیستم، پیش از SQL Server ، جهت بررسی گشوده و به علت حجم بالای آنها این قفلها تا مدتی رها نخواهند شد. در نتیجه آغاز سرویس SQL Server را با مشکلات جدی مواجه خواهند کرد که عموما عیب یابی آن کار سادهای نیست.
3- پیش فرض میزان حافظهی مصرفی SQL Server صحیح نیست. این مورد باید دقیقا بلافاصله پس از پایان عملیات نصب اولیه اصلاح شود. برای مطالعه بیشتر: تنظیمات پیشنهادی حداکثر حافظهی مصرفی اس کیوال سرور
4- آیا مطمئن هستید که از تمام امکانات نگارش جدید SQL Server ایی که نصب کردهاید در حال استفاده میباشید؟
برای مطالعه بیشتر: تنظیم درجه سازگاری یک دیتابیس اس کیوال سرور
5- بهتر است فشرده سازی خودکار بک آپها در SQL Server 2008 فعال شوند.
برای مطالعه بیشتر: +
6- از paging بیش از حد اطلاعات، از حافظهی فیزیکی سرور به virtual memory و انتقال آن به سخت دیسک سیستم جلوگیری کنید. برای این منظور:
در قسمت Run ویندوز تاپیک کنید : GPEDIT.MSC و پس از اجرای آن با مراجعه به Group policy editor ظاهر شده به مسیر زیر مراجعه کنید:
windows settings -> security settings -> local policies -> user rights assignment -> lock pages in memory
علاوه بر آن در همین قسمت (user rights assignment) گزینهی "Perform Volume Maintenance tasks" را نیز یافته و دسترسی لازم را به یوزر اکانت سرویس SQL Server بدهید.
7- به روز رسانی اطلاعات آماری SQL Server را به حالت غیرهمزمان تنظیم کنید.
اگر مطالب مرتبط با SQL Server این سایت را مرور کرده باشید حتما با یک سری DMV که دقیقا به شما خواهند گفت بر اساس اطلاعات آماری جمع شده برای مثال بهتر است روی چه فیلدهایی Index درست کنید، آشنا شدهاید. حالت پیش فرض به روز رسانی این اطلاعات آماری، synchronous است یا همزمان. به این معنا که تا اطلاعات آماری یک کوئری ذخیره نشود، حاصل کوئری به کاربر بازگشت داده نخواهد شد که این امر میتواند بر روی کارآیی سیستم تاثیر گذار باشد. اما امکان تنظیم آن به حالت غیر همزمان نیز مطابق کوئریهای زیر وجود دارد (این مورد از SQL Server 2005 به بعد اضافه شده است):
ALTER DATABASE dbName SET AUTO_UPDATE_STATISTICS ON
ALTER DATABASE dbName SET AUTO_UPDATE_STATISTICS_ASYNC ON
8- نصب آخرین سرویس پک موجود فراموش نشود. برای مثال این سایت آمار تمام به روز رسانیها را نگهداری میکند.
9- حتما رویهای را برای تهیه بک آپهای خودکار پیش بینی کنید. برای مثال : +
10- میزان فضای خالی باقیمانده درایوهای سرور را مونیتور کنید. اطلاعات بیشتر: +
11- با نصب سرور جدید و تنظیم collation آن به فارسی، به نکات "یافتن تداخلات Collations در SQL Server" دقت داشته باشید.
تراکنشها در RavenDB
ACID چیست؟
ACID از 4 قاعده تشکیل شده است (Atomic, Consistent, Isolated, and Durable) که با کنار هم قرار دادن آنها یک تراکنش مفهوم پیدا میکند:
الف) Atomic: به معنای همه یا هیچ
اگر تراکنشی از چندین تغییر تشکیل میشود، همهی آنها باید با موفقیت انجام شوند، یا اینکه هیچکدام از تغییرات نباید فرصت اعمال نهایی را بیابند.
برای مثال انتقال مبلغ X را از یک حساب، به حسابی دیگر درنظر بگیرید. در این حالت X ریال از حساب شخص کسر و X ریال به حساب شخص دیگری واریز خواهد شد. اگر موجودی حساب شخص، دارای X ریال نباشد، نباید مبلغی از این حساب کسر شود. مرحله اول شکست خورده است؛ بنابراین کل عملیات لغو میشود. همچنین اگر حساب دریافت کننده بسته شده باشد نیز نباید مبلغی از حساب اول کسر گردد و در این حالت نیز کل تراکنش باید برگشت بخورد.
ب) Consistent یا یکپارچه
در اینجا consistency علاوه بر اعمال قیود، به معنای اطلاعاتی است که بلافاصله پس از پایان تراکنشی از سیستم قابل دریافت و خواندن است.
ج) Isolated: محصور شده
اگر چندین تراکنش در یک زمان با هم در حال اجرا باشند، نتیجه نهایی با حالتی که تراکنشها یکی پس از دیگری اجرا میشوند باید یکی باشد.
د) Durable: ماندگار
اگر سیستم پایان تراکنشی را اعلام میکند، این مورد به معنای 100 درصد نوشته شدن اطلاعات در سخت دیسک باید باشد.
مراحل چهارگانه ACID در RavenDB به چه نحوی وجود دارند؟
RavebDB از هر دو نوع تراکنشهای implicit و explicit پشتیبانی میکند. Implicit به این معنا است که در حین استفاده معمول از RavenDB (و بدون انجام تنظیمات خاصی)، به صورت خودکار مفهوم تراکنشها وجود داشته و اعمال میشوند. برای نمونه به متد ذیل توجه نمائید:
public void TransferMoney(string fromAccountNumber, string toAccountNumber, decimal amount) { using(var session = Store.OpenSession()) { session.Advanced.UseOptimisticConcurrency = true; var fromAccount = session.Load<Account>("Accounts/" + fromAccountNumber); var toAccount = session.Load<Account>("Accounts/" + toAccountNumber); fromAccount.Balance -= amount; toAccount.Balance += amount; session.SaveChanges(); } }
- از document store ایی که پیشتر تدارک دیده شده، جهت بازکردن یک سشن استفاده شده است.
- به سشن صراحتا عنوان شده است که از Optimistic Concurrency استفاده کند. در این حالت RavenDB اطمینان حاصل میکند که اکانتهای بارگذاری شده توسط متدهای Load، تا زمان فراخوانی SaveChanges تغییر پیدا نکردهاند (و در غیراینصورت یک استثناء را صادر میکند).
- دو اکانت بر اساس Id آنها از بانک اطلاعاتی واکشی میشوند.
- موجودی یکی تقلیل یافته و موجودی دیگر، افزایش مییابد.
- متد SaveChanges بر روی شیء سشن فراخوانی شده است. تا زمانیکه این متد فراخوانی نشده است، کلیه تغییرات در حافظه نگهداری میشوند و به سرور ارسال نخواهند شد. فراخوانی آن سبب کامل شدن تراکنش و ارسال اطلاعات به سرور میگردد.
بنابراین شیء سشن بیانگر یک atomic transaction ماندگار و محصور شده است (سه جزء ACID تاکنون محقق شدهاند). محصور شده بودن آن به این معنا است که:
الف) هر تغییری که در سشن اعمال میشود، تا پیش از فراخوانی متد SaveChanges از دید سایر تراکنشها مخفی است.
ب) اگر دو تراکنش همزمان رخ دهند، تغییرات هیچکدام بر روی دیگری اثری ندارد.
اما Consistency یا یکپارچگی در RavenDB بستگی دارد به نحوهی خواندن اطلاعات و این مورد با دنیای رابطهای اندکی متفاوت است که در ادامه جزئیات آنرا بیشتر بررسی خواهیم کرد.
عاقبت یک دست شدن یا eventual consistency
درک Consistency مفهوم ACID در RavenDB بسیار مهم است و عدم آشنایی با نحوه عملکرد آن میتواند مشکلساز شود. در دنیای بانکهای اطلاعاتی رابطهای، برنامه نویسها به «immediate consistency» عادت دارند (یکپارچگی آنی). به این معنا که هرگونه تغییری در بانک اطلاعاتی، پس از پایان تراکنش، بلافاصله در اختیار کلیه خوانندگان سیستم قرار میگیرد. در RavenDB و خصوصا دنیای NoSQL، این یکپارچگی آنی دنیای رابطهای، به «eventual consistency» تبدیل میشود (عاقبت یکدست شدن). عاقبت یک دست شدن در RavenDB به این معنا است که اگر تغییری به یک سند اعمال گردیده و ذخیره شود؛ کوئری انجام شده بر روی این اطلاعات تغییر یافته ممکن است «stale data» باز گرداند. واژه stale در RavenDB به این معنا است که هنوز اطلاعاتی در دیتابیس موجود هستند که جهت تکمیل ایندکسها پردازش نشدهاند. به این مورد در قسمت بررسی ایندکسها در RavenDB اشاره شد.
در RavenDB یک سری تردهای پشت صحنه، مدام مشغول به کار هستند و بدون کند کردن عملیات سیستم، کار ایندکس کردن اطلاعات را انجام میدهند. هر زمانیکه اطلاعاتی را ذخیره میکنیم، بلافاصله این تردها تغییرات را تشخیص داده و ایندکسها را به روز رسانی میکنند. همچنین باید درنظر داشت که RavenDB جزو معدود بانکهای اطلاعاتی است که خودش را بر اساس نحوه استفاده شما ایندکس میکند! (نمونهای از آنرا در قسمت ایندکسهای پویای حاصل از کوئریهای LINQ پیشتر مشاهده کردهاید)
نکته مهم
در RavenDB اگر از کوئریهای LINQ استفاده کنیم، ممکن است به علت اینکه هنوز تردهای پشت صحنهی ایندکس سازی اطلاعات، کارشان تمام نشده است، تمام اطلاعات یا آخرین اطلاعات را دریافت نکنیم (که به آن stale data گفته میشود). هر آنچه که ایندکس شده است دریافت میگردد (مفهوم عاقبت یک دست شدن ایندکسها). اما اگر نیاز به یکپارچگی آنی داشتیم، متد Load یک سشن، مستقیما به بانک اطلاعاتی مراجعه میکند و اطلاعات بازگشت داده شده توسط آن هیچگاه احتمال stale بودن را ندارند.
بنابراین برای نمایش اطلاعات یا گزارشگیری، از کوئریهای LINQ استفاده کنید. RavenDB خودش را بر اساس کوئری شما ایندکس خواهد کرد و نهایتا به کوئریهایی فوق العاده سریعی در طول کارکرد سیستم خواهیم رسید. اما در صفحه ویرایش اطلاعات بهتر است از متد Load استفاده گردد تا نیاز به مفهوم immediate consistency یا یکپارچگی آنی برآورده شود.
تنظیمات خاص کار با ایندکس سازها برای انتظار جهت اتمام کار آنها
عنوان شد که اگر ایندکس سازهای پشت صحنه هنوز کارشان تمام نشده است، در حین کوئری گرفتن، هر آنچه که ایندکس شده بازگشت داده میشود.
در اینجا میتوان به RavenDB گفت که تا چه زمانی میتواند یک کوئری را جهت دریافت اطلاعات نهایی به تاخیر بیندازد. برای اینکار باید اندکی کوئریهای LINQ آنرا سفارشی سازی کنیم:
RavenQueryStatistics stats; var results = session.Query<Product>() .Statistics(out stats) .Where(x => x.Price > 10) .ToArray(); if (stats.IsStale) { // Results are known to be stale }
همچنین زمان انتظار تا پایان کار ایندکس ساز را نیز توسط متد Customize به نحو ذیل میتوان تنظیم کرد:
RavenQueryStatistics stats; var results = session.Query<Product>() .Statistics(out stats) .Where(x => x.Price > 10) .Customize(x => x.WaitForNonStaleResults(TimeSpan.FromSeconds(5))) .ToArray();
documentStore.Conventions.DefaultQueryingConsistency = ConsistencyOptions.QueryYourWrites;
while (documentStore.DatabaseCommands.GetStatistics().StaleIndexes.Length != 0) { Thread.Sleep(10); }
مقابله با تداخلات همزمانی
با تنظیم session.Advanced.UseOptimisticConcurrency = true، اگر سندی که در حال ویرایش است، در این حین توسط کاربر دیگری تغییر کرده باشد، استثنای ConcurrencyException صادر خواهد شد. همچنین این استثناء در صورتیکه شخصی قصد بازنویسی سند موجودی را داشته باشد نیز صادر خواهد شد (شخصی بخواهد سندی را با ID سند موجودی ذخیره کند). اگر از optimistic concurrency استفاده نشود، آخرین ترد نویسنده یا به روز کننده اطلاعات، برنده خواهد شد و اطلاعات نهایی موجود در بانک اطلاعاتی متعلق به او و حاصل بازنویسی آن ترد است.
optimistic concurrency به زبان ساده به معنای به خاطر سپردن شماره نگارش یک سند است، زمانیکه آنرا بارگذاری میکنیم و سپس ارسال آن به سرور، زمانیکه قصد ذخیره آنرا داریم. در SQL Server اینکار توسط RowVersion انجام میشود. در بانکهای اطلاعاتی سندگرا چون تمایل به استفاده از HTTP در آنها زیاد است (مانند RavenDB) از مکانیزمی به نام E-Tag برای این منظور کمک گرفته میشود. هر زمانیکه تغییری به یک سند اعمال میشود، E-Tag آن به صورت خودکار افزایش خواهد یافت.
برای مثال فرض کنید کاربری سندی را با E-Tag مساوی 2 بارگذاری کرده است. قبل از اینکه این کاربر در صفحه ویرایش اطلاعات کارش با این سند خاتمه یابد، کاربر دیگری در شبکه، این سند را ویرایش کرده است و اکنون E-Tag آن مثلا مساوی 6 است. در این زمان اگر کاربر یک سعی به ذخیره سازی اطلاعات نماید، چون E-Tag سند او با E-Tag سند موجود در سرور دیگر یکی نیست، با استثنای ConcurrencyException متوقف خواهد شد.
مشکل! در برنامههای بدون حالت وب، چون پس از نمایش صفحه ویرایش اطلاعات، سشن RavenDB نیز بلافاصله Dispose خواهد شد، این E-Tag را از دست خواهیم داد. همچنین باید دقت داشت که سشن RavenDB به هیچ عنوان نباید در طول عمر یک برنامه باز نگهداشته شود و برای طول عمری کوتاه طراحی شده است. راه حلی که برای آن درنظر گرفته شده است، ذخیره سازی این E-Tag در بار اول دریافت آن از سشن میباشد. برای این منظور تنها کافی است خاصیتی را به نام Etag با ویژگی JsonIgnore (که سبب عدم ذخیره سازی آن در بانک اطلاعاتی خواهد شد) تعریف کنیم:
public class Person { public string Id { get; set; } [JsonIgnore] public Guid? Etag { get; set; } public string Name { get; set; } }
public Person Get(string id) { var person = session.Load<Person>(id); person.Etag = session.Advanced.GetEtagFor(person); return person; }
public void Update(Person person) { session.Advanced.UseOptimisticConcurrency = true; session.Store(person, person.Etag, person.Id); session.SaveChanges(); person.Etag = session.Advanced.GetEtagFor(person); }
تراکنشهای صریح
همانطور که عنوان شد، به صورت ضمنی کلیه سشنها، یک واحد کار را تشکیل داده و با پایان آنها، تراکنش خاتمه مییابد. اگر به هر علتی قصد تغییر این رفتار ضمنی پیش فرض را دارید، امکان تعریف صریح تراکنشهای نیز وجود دارد:
using (var transaction = new TransactionScope()) { using (var session1 = store.OpenSession()) { session1.Store(new Account()); session1.SaveChanges(); } using (var session2 = store.OpenSession()) { session2.Store(new Account()); session2.SaveChanges(); } transaction.Complete(); }
DARPA Wants All C Converted To Rust
After more than two decades of grappling with memory safety issues in C and C++, the software engineering community has reached a consensus. It’s not enough to rely on bug-finding tools. The preferred approach is to use “safe” programming languages that can reject unsafe programs at compile time, thereby preventing the emergence of memory safety issues.
Although most of the attention is on .NET Core, development continues on the original .NET Framework. Microsoft has recently released a preview of .NET Framework 4.7.2 with updates to ASP.NET, ADO.NET, WCF, WPF, and even Windows Forms. You can see the complete release notes on GitHub.